﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using RLProject1;
using RLProject1.Model.AMEEWorld;
using System.Windows;

namespace RLProjectUnitTest
{
    [TestClass]
    public class WorldImageTest
    {
        /// <summary>
        /// Testwelt u = x - y,
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <returns>x - y</returns>
        double Testwelt(double x, double y) {
            return x - y;
        }

        WorldImage getNewTestObject() {
            // 2 Sektoren, 2 Spuren mit 1 und 2 Metern. Je Abschnitt 3 Messpunkte in Reihe und 2 in Linie
            Tiling tiling = new Tiling(2, 2, new float[] { 1f, 2f });
            var testObject = new WorldImage(tiling, 2, 3, Testwelt);
            return testObject;
        }


        [TestMethod]
        public void CheckInitPreConditions_SpurenUndSektorenanzahlNegativ_ThrowException() {
            WorldImage testObject;
            Tiling tiling;
            try {
                tiling = new Tiling(2, -2, new float[] { 1f, 2f });
                testObject = new WorldImage(tiling, 2, 3, Testwelt);
            }
            catch (RLProjectException) {
                return;
            }
            Assert.Fail("keine Exception geworfen.");
        }


        //[TestMethod]
        //public void CheckInitPreConditions_ZuwenigRadien_ThrowException() {
        //    WorldImage testObject;
        //    try {
        //        testObject = new WorldImage(2, 2, new float[] { 1f }, 2, 3, Testwelt);
        //    }
        //    catch (RLProjectException) {
        //        return;
        //    }
        //    Assert.Fail("Keine Exception geworfen bei zu wenig Radien.");
        //}


        [TestMethod]
        public void CheckInitPreConditions_TestWeltNull_ThrowException() {
            WorldImage testObject;
            Tiling tiling = new Tiling(1, 2, new float[] { 1f });
            try {
                testObject = new WorldImage(tiling, 2, 3, null);
            }
            catch (RLProjectException) {
                return;
            }
            catch (ArgumentNullException) {
                return;
            }
            Assert.Fail("Keine Exception geworfen bei zu wenig Radien.");
        }


        [TestMethod]
        public void CheckInitPreConditions_RadienNull_ThrowException() {
            WorldImage testObject;
            Tiling tiling;
            try {
                tiling = new Tiling(1, 2, null);
                testObject = new WorldImage(tiling, 2, 3, Testwelt);
            }
            catch (RLProjectException) {
                return;
            }
            catch (ArgumentNullException) {
                return;
            }
            Assert.Fail("Keine Exception geworfen bei zu wenig Radien.");
        }

        [TestMethod]
        public void InitMessRadien() {
            var testObject = this.getNewTestObject();
            Vector[] messPunkte = testObject.GetMesspunkte();

            Assert.IsNotNull(messPunkte, "GetMesspunkte() liefert null");

            int anzahlErwartet = 24;
            Assert.AreEqual<int>(anzahlErwartet, messPunkte.Length, "Anzahl der Messpunkte stimmt nicht. Soll: {0}, Ist: {1}", anzahlErwartet, messPunkte.Length);

            double produktX = 1;
            for (int i = 0; i < 6; i++) {
                produktX *= messPunkte[i].X;
            }
            for (int i = 12; i < 18; i++) {
                produktX *= messPunkte[i].X;
            }
            Assert.IsTrue((produktX != 0), "Ein X-Wert ist 0!");
            Assert.IsTrue((produktX > 0), "Anordnung der Messpunkte nicht wie erwartet. Sektor 0 X-Werte sollten alle positiv sein.");

            double produktY = 1;
            for (int i = 4; i < 8; i++) {
                produktY *= messPunkte[i].Y;
            }
            for (int i = 16; i < 20; i++) {
                produktY *= messPunkte[i].Y;
            }
            Assert.IsTrue((produktY != 0), "Ein Y-Wert ist unerwartet 0. (Index 4-7,16-19)");
            Assert.IsTrue((produktY > 0), "Anordnung der Messpunkte nicht wie erwartet. Y-Werte (Index 4-7,16-19) sollten alle positiv sein.");

            produktX = 1;
            for (int i = 6; i < 12; i++) {
                produktX *= -messPunkte[i].X;
            }
            for (int i = 18; i < 24; i++) {
                produktX *= -messPunkte[i].X;
            }
            Assert.IsTrue((produktX != 0), "Ein X-Wert ist 0!");
            Assert.IsTrue((produktX > 0), "Anordnung der Messpunkte nicht wie erwartet. Sektor 1 X-Werte sollten alle negativ sein.");

        }


    }
}
